Ref와 useRef
✒️ 2025-05-28 10:44 내용 수정
Ref
DOM 노드나 React element를 참조할 수 있는 방법을 제공함
- 참고 자료 : React legacy Ref와 DOM, React Referencing Values with Refs
ref.current속성으로 현재 참조하고 있는 대상의 값에 접근할 수 있으며, 해당 값은 변이(읽고 쓰기)될 수 있다.console.log(ref)를 사용하면 특정 DOM을 클릭하거나 했을 때 해당 요소가 출력된다.- 사진은 Axios로 서버와 연결하기에서 드롭다운 Component에 ref 관련 이벤트 처리를 실습할 때
useRef()로 얻은 ref가 어떤 요소를 참조하는지 확인하기 위해 테스트한 결과이다.
- state처럼 ref도 React에서 리렌더링되면 값을 다시 얻어온다.
- state와 가장 큰 차이점은 ref를 변경해도 React는 Component를 다시 렌더링하지 않는다.
- 각 Component에 로컬로 저장되며, 리렌더링을 촉발하지 않기 때문에 리렌더링 사이에 정보를 저장할 수 있다.
- Ref와 State 차이점 비교 참고 자료(표) : React Differences between refs and state
| ref | state |
|---|---|
useRef(initialValue)로 {current:initialValue} 획득 |
useState(initialValue)로 [value, setValue] 반환 |
| 값이 변경될 때 re-render가 발생하지 않음 | 값이 바뀌면 re-render가 발생함 |
Mutable(변이 가능) - 렌더링 과정 외에 current를 변경가능 |
Immutable - setValue()로만 변경하여 re-render를 촉발시킴 |
렌더링 중에 current 값을 읽거나 쓰면 안됨 |
언제든 state를 읽을 수는 있지만, 각 render는 변하지 않는 state의 snapshot을 가짐 |
useRef(Ref Hook)
렌더링에 필요하지 않은 값을 참조할 수 있는 Hook
- 참고 자료 : React useRef
- Component 최상위 레벨에서
useRef()를 호출해서 ref를 선언해서 사용하고,useRef()는 단일 property를 가진 객체를 반환한다.- initialValue : ref 객체의
currentproperty의 초기 설정값이며, 초기 렌더링 이후엔 무시된다.
- initialValue : ref 객체의
- 다음 렌더링에서
useRef()는 동일한 객체를 반환하며,currentproperty의 값을 변경할 수 있다.
import { useRef } from 'react';
function Test() {
const ref = useRef(initialValue); // 초기값, 초기 렌더링 이후엔 무시됨
}
- 주의사항
ref.currentproperty는 state와 달리 변이할 수 있기 때문에 렌더링에 사용되는 객체를 포함하는 경우 해당 객체를 변이해선 안된다.- 초기화 때를 제외하곤 렌더링 중에
ref.current를 읽거나 쓰는 경우 Component의 동작을 예측하기 어렵기 때문에 주의해야 한다.- Component 본문이 순수 함수처럼 동작하고, 입력값(props, state, context)이 동일하면 완전 동일한 JSX를 반환해야 하며, 다른 순서나 인수를 사용해도 다른 호출 결과에 영향을 미쳐선 안된다고 나와있다.
- 참고 자료 링크에서 Pitfall 부분에 따르면 Component는 이런 규칙을 어기더라도 작동은 하지만 React에 추가될 기능들은 이런 규칙에 의존하므로 지키는 것을 권장하고 있다.
import { useRef } from 'react';
function Test() {
{/* 렌더링 중에 ref를 작성하면 안된다 */}
ref.current = 'a';
{/* 렌더링 중에는 ref을 읽으면 안된다 */}
return <span>{ref.current}</span>
}
//////////////////////////////////////////
// 렌더링 중에 ref를 읽거나 써야 하는 경우 이벤트 핸들러나 Effect에서 수행한다.
function NewTest() {
// Effect로 ref를 읽거나 쓰기
useEffect(()=>{
ref.current = 'a';
})
// 이벤트 핸들러에서 ref를 읽거나 쓰기
function handleClick() {
clickAction(ref.current);
}
}